
#ifndef SHADER_PROGRAM
#define SHADER_PROGRAM


#include <string>
#include "libExt/libExt.h"
#include "Interfaces/IShader.h"
using namespace std;
namespace gengine
{
	namespace kernel
	{
class   GlShaderProgram:public IShaderProgram
{
protected:
    GLhandleARB      program;                            // program object handle
	GLhandleARB      vertexShader;
	GLhandleARB      fragmentShader;
	GLhandleARB      geometryShader;
    bool        ok;                                 // whether program is loaded and ready to be used
    string      glError;
    string      log;
	int shaderCompileStatus;
	
public:
    
	GlShaderProgram  ();
    ~GlShaderProgram ();

                                                  // load shaders
 
   
	//bool SetShaderSources(const char*vertexSrc,const char*fragmentSrc,const char*geometrySrc = 0);
	
	bool    LoadShaders ( const char * vertexFileName, const char * fragmentFileName ,const char * geometryFileName = 0);
	
	bool    LoadShader(GLhandleARB shader,const char *filename);

                                                    // remove all shaders and free all objects
    void    Clear ();


    string  GetLog     () const                         // get current log
    {
        return log;
    }

    bool    IsOk () const                               // whether shader is ok
    {
        return ok;
    }

    string  GetGlError () const
    {
        return glError;
    }

	ShaderProgramType  GetProgramType() const 
	{
		return GLSL_SHADER;
	}

	const GLhandleARB const &GetProgramObject() const
	{
		return program;
	}
    void    Bind   ();
    void    Unbind ();

                                                        // uniform variables handling methods
    bool        SetConstant  ( const char * name, const Vector4D& value  );
    bool        SetConstant  ( int loc,            const Vector4D& value );
    bool        SetConstant  ( const char * name, const Vector3D& value  );
    bool        SetConstant  ( int loc,            const Vector3D& value );
    bool        SetConstant  ( const char * name, const Vector2D& value  );
    bool        SetConstant  ( int loc,            const Vector2D& value );
    bool        SetConstant  ( const char * name, float value            );
    bool        SetConstant  ( int loc,            float value           );
    bool        SetConstant  ( const char * name, const Matrix4x4& value );
    bool        SetConstant  ( const char * name, const Matrix3D&  value );
    bool        SetConstant  ( const char * name, float value [16]       );
    bool        SetConstant  ( const char * name, int value              );
    bool        SetConstant   ( int loc,            int value            );
	
	

	// bool setTexture(const char*name,unsigned texId);
	///////////////////////////////////////////////////////////////////////////
	Vector4D    GetUniformVector  ( const char * name );
    Vector4D    GetUniformVector  ( int loc            );
    int         LocForUniformName ( const char * name );

                                                        // attribute variables handling methods
    bool        SetAttribute     ( const char * name, const Vector4D& value );
    bool        SetAttribute     ( int index,         const Vector4D& value );
    Vector4D    GetAttribute     ( const char * name );
    Vector4D    GetAttribute     ( int index );
    int         IndexForAttrName ( const char * name );
    bool        BindAttributeTo  ( int no, const char * name );

    bool    	SetTexture ( const char * name, unsigned texUnit );
    bool    	SetTexture ( int loc,           int texUnit );

                                                        // check whether there is a support for GLSL
    static  bool    IsSupported ();
    static  string  Version     ();
                                                        // some limitations on program
    static  int MaxVertexUniformComponents   ();
    static  int MaxVertexAttribs             ();
    static  int MaxFragmentTextureUnits      ();
    static  int MaxVertexTextureUnits        ();
    static  int MaxCombinedTextureUnits      ();
    static  int MaxVaryingFloats             ();
    static  int MaxFragmentUniformComponents ();
    static  int MaxTextureCoords             ();

protected:
  //  bool    loadShader   ( GLhandleARB shader, Data * data );
    bool    CheckGlError ();
    void    LoadLog      ( GLhandleARB object );
};
}
}
#endif
